1   /*
2    * Copyright (C) 2009 The Guava Authors
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package com.google.common.collect;
18  
19  import static com.google.common.base.Preconditions.checkArgument;
20  import static com.google.common.base.Preconditions.checkNotNull;
21  import static com.google.common.collect.Maps.keyOrNull;
22  
23  import com.google.common.annotations.GwtCompatible;
24  
25  import java.util.Arrays;
26  import java.util.Collections;
27  import java.util.Comparator;
28  import java.util.Map;
29  import java.util.NavigableMap;
30  import java.util.SortedMap;
31  import java.util.TreeMap;
32  
33  import javax.annotation.Nullable;
34  
35  /**
36   * An immutable {@link SortedMap}. Does not permit null keys or values.
37   *
38   * <p>Unlike {@link Collections#unmodifiableSortedMap}, which is a <i>view</i>
39   * of a separate map which can still change, an instance of {@code
40   * ImmutableSortedMap} contains its own data and will <i>never</i> change.
41   * {@code ImmutableSortedMap} is convenient for {@code public static final} maps
42   * ("constant maps") and also lets you easily make a "defensive copy" of a map
43   * provided to your class by a caller.
44   *
45   * <p><b>Note:</b> Although this class is not final, it cannot be subclassed as
46   * it has no public or protected constructors. Thus, instances of this class are
47   * guaranteed to be immutable.
48   *
49   * <p>See the Guava User Guide article on <a href=
50   * "http://code.google.com/p/guava-libraries/wiki/ImmutableCollectionsExplained">
51   * immutable collections</a>.
52   *
53   * @author Jared Levy
54   * @author Louis Wasserman
55   * @since 2.0 (imported from Google Collections Library; implements {@code
56   *        NavigableMap} since 12.0)
57   */
58  @GwtCompatible(serializable = true, emulated = true)
59  public abstract class ImmutableSortedMap<K, V>
60      extends ImmutableSortedMapFauxverideShim<K, V> implements NavigableMap<K, V> {
61    /*
62     * TODO(kevinb): Confirm that ImmutableSortedMap is faster to construct and
63     * uses less memory than TreeMap; then say so in the class Javadoc.
64     */
65    private static final Comparator<Comparable> NATURAL_ORDER = Ordering.natural();
66  
67    private static final ImmutableSortedMap<Comparable, Object> NATURAL_EMPTY_MAP =
68        new EmptyImmutableSortedMap<Comparable, Object>(NATURAL_ORDER);
69  
70    static <K, V> ImmutableSortedMap<K, V> emptyMap(Comparator<? super K> comparator) {
71      if (Ordering.natural().equals(comparator)) {
72        return of();
73      } else {
74        return new EmptyImmutableSortedMap<K, V>(comparator);
75      }
76    }
77  
78    static <K, V> ImmutableSortedMap<K, V> fromSortedEntries(
79        Comparator<? super K> comparator,
80        int size,
81        Entry<K, V>[] entries) {
82      if (size == 0) {
83        return emptyMap(comparator);
84      }
85  
86      ImmutableList.Builder<K> keyBuilder = ImmutableList.builder();
87      ImmutableList.Builder<V> valueBuilder = ImmutableList.builder();
88      for (int i = 0; i < size; i++) {
89        Entry<K, V> entry = entries[i];
90        keyBuilder.add(entry.getKey());
91        valueBuilder.add(entry.getValue());
92      }
93  
94      return new RegularImmutableSortedMap<K, V>(
95          new RegularImmutableSortedSet<K>(keyBuilder.build(), comparator),
96          valueBuilder.build());
97    }
98  
99    static <K, V> ImmutableSortedMap<K, V> from(
100       ImmutableSortedSet<K> keySet, ImmutableList<V> valueList) {
101     if (keySet.isEmpty()) {
102       return emptyMap(keySet.comparator());
103     } else {
104       return new RegularImmutableSortedMap<K, V>(
105           (RegularImmutableSortedSet<K>) keySet,
106           valueList);
107     }
108   }
109 
110   /**
111    * Returns the empty sorted map.
112    */
113   @SuppressWarnings("unchecked")
114   // unsafe, comparator() returns a comparator on the specified type
115   // TODO(kevinb): evaluate whether or not of().comparator() should return null
116   public static <K, V> ImmutableSortedMap<K, V> of() {
117     return (ImmutableSortedMap<K, V>) NATURAL_EMPTY_MAP;
118   }
119 
120   /**
121    * Returns an immutable map containing a single entry.
122    */
123   public static <K extends Comparable<? super K>, V>
124       ImmutableSortedMap<K, V> of(K k1, V v1) {
125     return from(ImmutableSortedSet.of(k1), ImmutableList.of(v1));
126   }
127 
128   /**
129    * Returns an immutable sorted map containing the given entries, sorted by the
130    * natural ordering of their keys.
131    *
132    * @throws IllegalArgumentException if the two keys are equal according to
133    *     their natural ordering
134    */
135   @SuppressWarnings("unchecked")
136   public static <K extends Comparable<? super K>, V> ImmutableSortedMap<K, V>
137       of(K k1, V v1, K k2, V v2) {
138     return fromEntries(Ordering.natural(), false, 2, entryOf(k1, v1), entryOf(k2, v2));
139   }
140 
141   /**
142    * Returns an immutable sorted map containing the given entries, sorted by the
143    * natural ordering of their keys.
144    *
145    * @throws IllegalArgumentException if any two keys are equal according to
146    *     their natural ordering
147    */
148   @SuppressWarnings("unchecked")
149   public static <K extends Comparable<? super K>, V> ImmutableSortedMap<K, V>
150       of(K k1, V v1, K k2, V v2, K k3, V v3) {
151     return fromEntries(Ordering.natural(), false, 3, entryOf(k1, v1), entryOf(k2, v2), 
152         entryOf(k3, v3));
153   }
154 
155   /**
156    * Returns an immutable sorted map containing the given entries, sorted by the
157    * natural ordering of their keys.
158    *
159    * @throws IllegalArgumentException if any two keys are equal according to
160    *     their natural ordering
161    */
162   @SuppressWarnings("unchecked")
163   public static <K extends Comparable<? super K>, V> ImmutableSortedMap<K, V>
164       of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) {
165     return fromEntries(Ordering.natural(), false, 4, entryOf(k1, v1), entryOf(k2, v2), 
166         entryOf(k3, v3), entryOf(k4, v4));
167   }
168 
169   /**
170    * Returns an immutable sorted map containing the given entries, sorted by the
171    * natural ordering of their keys.
172    *
173    * @throws IllegalArgumentException if any two keys are equal according to
174    *     their natural ordering
175    */
176   @SuppressWarnings("unchecked")
177   public static <K extends Comparable<? super K>, V> ImmutableSortedMap<K, V>
178       of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5) {
179     return fromEntries(Ordering.natural(), false, 5, entryOf(k1, v1), entryOf(k2, v2), 
180         entryOf(k3, v3), entryOf(k4, v4), entryOf(k5, v5));
181   }
182 
183   /**
184    * Returns an immutable map containing the same entries as {@code map}, sorted
185    * by the natural ordering of the keys.
186    *
187    * <p>Despite the method name, this method attempts to avoid actually copying
188    * the data when it is safe to do so. The exact circumstances under which a
189    * copy will or will not be performed are undocumented and subject to change.
190    *
191    * <p>This method is not type-safe, as it may be called on a map with keys
192    * that are not mutually comparable.
193    *
194    * @throws ClassCastException if the keys in {@code map} are not mutually
195    *         comparable
196    * @throws NullPointerException if any key or value in {@code map} is null
197    * @throws IllegalArgumentException if any two keys are equal according to
198    *         their natural ordering
199    */
200   public static <K, V> ImmutableSortedMap<K, V> copyOf(
201       Map<? extends K, ? extends V> map) {
202     // Hack around K not being a subtype of Comparable.
203     // Unsafe, see ImmutableSortedSetFauxverideShim.
204     @SuppressWarnings("unchecked")
205     Ordering<K> naturalOrder = (Ordering<K>) Ordering.<Comparable>natural();
206     return copyOfInternal(map, naturalOrder);
207   }
208 
209   /**
210    * Returns an immutable map containing the same entries as {@code map}, with
211    * keys sorted by the provided comparator.
212    *
213    * <p>Despite the method name, this method attempts to avoid actually copying
214    * the data when it is safe to do so. The exact circumstances under which a
215    * copy will or will not be performed are undocumented and subject to change.
216    *
217    * @throws NullPointerException if any key or value in {@code map} is null
218    * @throws IllegalArgumentException if any two keys are equal according to the
219    *         comparator
220    */
221   public static <K, V> ImmutableSortedMap<K, V> copyOf(
222       Map<? extends K, ? extends V> map, Comparator<? super K> comparator) {
223     return copyOfInternal(map, checkNotNull(comparator));
224   }
225 
226   /**
227    * Returns an immutable map containing the same entries as the provided sorted
228    * map, with the same ordering.
229    *
230    * <p>Despite the method name, this method attempts to avoid actually copying
231    * the data when it is safe to do so. The exact circumstances under which a
232    * copy will or will not be performed are undocumented and subject to change.
233    *
234    * @throws NullPointerException if any key or value in {@code map} is null
235    */
236   @SuppressWarnings("unchecked")
237   public static <K, V> ImmutableSortedMap<K, V> copyOfSorted(
238       SortedMap<K, ? extends V> map) {
239     Comparator<? super K> comparator = map.comparator();
240     if (comparator == null) {
241       // If map has a null comparator, the keys should have a natural ordering,
242       // even though K doesn't explicitly implement Comparable.
243       comparator = (Comparator<? super K>) NATURAL_ORDER;
244     }
245     return copyOfInternal(map, comparator);
246   }
247 
248   private static <K, V> ImmutableSortedMap<K, V> copyOfInternal(
249       Map<? extends K, ? extends V> map, Comparator<? super K> comparator) {
250     boolean sameComparator = false;
251     if (map instanceof SortedMap) {
252       SortedMap<?, ?> sortedMap = (SortedMap<?, ?>) map;
253       Comparator<?> comparator2 = sortedMap.comparator();
254       sameComparator = (comparator2 == null)
255           ? comparator == NATURAL_ORDER
256           : comparator.equals(comparator2);
257     }
258 
259     if (sameComparator && (map instanceof ImmutableSortedMap)) {
260       // TODO(kevinb): Prove that this cast is safe, even though
261       // Collections.unmodifiableSortedMap requires the same key type.
262       @SuppressWarnings("unchecked")
263       ImmutableSortedMap<K, V> kvMap = (ImmutableSortedMap<K, V>) map;
264       if (!kvMap.isPartialView()) {
265         return kvMap;
266       }
267     }
268 
269     // "adding" type params to an array of a raw type should be safe as
270     // long as no one can ever cast that same array instance back to a
271     // raw type.
272     @SuppressWarnings("unchecked")
273     Entry<K, V>[] entries = map.entrySet().toArray(new Entry[0]);
274 
275     return fromEntries(comparator, sameComparator, entries.length, entries);
276   }
277   
278   static <K, V> ImmutableSortedMap<K, V> fromEntries(
279       Comparator<? super K> comparator, boolean sameComparator, int size, Entry<K, V>... entries) {
280     for (int i = 0; i < size; i++) {
281       Entry<K, V> entry = entries[i];
282       entries[i] = entryOf(entry.getKey(), entry.getValue());
283     }
284     if (!sameComparator) {
285       sortEntries(comparator, size, entries);
286       validateEntries(size, entries, comparator);
287     }
288 
289     return fromSortedEntries(comparator, size, entries);
290   }
291 
292   private static <K, V> void sortEntries(
293       final Comparator<? super K> comparator, int size, Entry<K, V>[] entries) {
294     Arrays.sort(entries, 0, size, Ordering.from(comparator).<K>onKeys());
295   }
296 
297   private static <K, V> void validateEntries(int size, Entry<K, V>[] entries,
298       Comparator<? super K> comparator) {
299     for (int i = 1; i < size; i++) {
300       checkNoConflict(comparator.compare(entries[i - 1].getKey(), entries[i].getKey()) != 0, "key",
301           entries[i - 1], entries[i]);
302     }
303   }
304 
305   /**
306    * Returns a builder that creates immutable sorted maps whose keys are
307    * ordered by their natural ordering. The sorted maps use {@link
308    * Ordering#natural()} as the comparator.
309    */
310   public static <K extends Comparable<?>, V> Builder<K, V> naturalOrder() {
311     return new Builder<K, V>(Ordering.natural());
312   }
313 
314   /**
315    * Returns a builder that creates immutable sorted maps with an explicit
316    * comparator. If the comparator has a more general type than the map's keys,
317    * such as creating a {@code SortedMap<Integer, String>} with a {@code
318    * Comparator<Number>}, use the {@link Builder} constructor instead.
319    *
320    * @throws NullPointerException if {@code comparator} is null
321    */
322   public static <K, V> Builder<K, V> orderedBy(Comparator<K> comparator) {
323     return new Builder<K, V>(comparator);
324   }
325 
326   /**
327    * Returns a builder that creates immutable sorted maps whose keys are
328    * ordered by the reverse of their natural ordering.
329    */
330   public static <K extends Comparable<?>, V> Builder<K, V> reverseOrder() {
331     return new Builder<K, V>(Ordering.natural().reverse());
332   }
333 
334   /**
335    * A builder for creating immutable sorted map instances, especially {@code
336    * public static final} maps ("constant maps"). Example: <pre>   {@code
337    *
338    *   static final ImmutableSortedMap<Integer, String> INT_TO_WORD =
339    *       new ImmutableSortedMap.Builder<Integer, String>(Ordering.natural())
340    *           .put(1, "one")
341    *           .put(2, "two")
342    *           .put(3, "three")
343    *           .build();}</pre>
344    *
345    * <p>For <i>small</i> immutable sorted maps, the {@code ImmutableSortedMap.of()}
346    * methods are even more convenient.
347    *
348    * <p>Builder instances can be reused - it is safe to call {@link #build}
349    * multiple times to build multiple maps in series. Each map is a superset of
350    * the maps created before it.
351    *
352    * @since 2.0 (imported from Google Collections Library)
353    */
354   public static class Builder<K, V> extends ImmutableMap.Builder<K, V> {
355     private final Comparator<? super K> comparator;
356 
357     /**
358      * Creates a new builder. The returned builder is equivalent to the builder
359      * generated by {@link ImmutableSortedMap#orderedBy}.
360      */
361     @SuppressWarnings("unchecked")
362     public Builder(Comparator<? super K> comparator) {
363       this.comparator = checkNotNull(comparator);
364     }
365 
366     /**
367      * Associates {@code key} with {@code value} in the built map. Duplicate
368      * keys, according to the comparator (which might be the keys' natural
369      * order), are not allowed, and will cause {@link #build} to fail.
370      */
371     @Override public Builder<K, V> put(K key, V value) {
372       super.put(key, value);
373       return this;
374     }
375 
376     /**
377      * Adds the given {@code entry} to the map, making it immutable if
378      * necessary. Duplicate keys, according to the comparator (which might be
379      * the keys' natural order), are not allowed, and will cause {@link #build}
380      * to fail.
381      *
382      * @since 11.0
383      */
384     @Override public Builder<K, V> put(Entry<? extends K, ? extends V> entry) {
385       super.put(entry);
386       return this;
387     }
388 
389     /**
390      * Associates all of the given map's keys and values in the built map.
391      * Duplicate keys, according to the comparator (which might be the keys'
392      * natural order), are not allowed, and will cause {@link #build} to fail.
393      *
394      * @throws NullPointerException if any key or value in {@code map} is null
395      */
396     @Override public Builder<K, V> putAll(Map<? extends K, ? extends V> map) {
397       super.putAll(map);
398       return this;
399     }
400 
401     /**
402      * Returns a newly-created immutable sorted map.
403      *
404      * @throws IllegalArgumentException if any two keys are equal according to
405      *     the comparator (which might be the keys' natural order)
406      */
407     @Override public ImmutableSortedMap<K, V> build() {
408       return fromEntries(comparator, false, size, entries);
409     }
410   }
411 
412   ImmutableSortedMap() {
413   }
414 
415   ImmutableSortedMap(ImmutableSortedMap<K, V> descendingMap) {
416     this.descendingMap = descendingMap;
417   }
418 
419   @Override
420   public int size() {
421     return values().size();
422   }
423 
424   @Override public boolean containsValue(@Nullable Object value) {
425     return values().contains(value);
426   }
427 
428   @Override boolean isPartialView() {
429     return keySet().isPartialView() || values().isPartialView();
430   }
431 
432   /**
433    * Returns an immutable set of the mappings in this map, sorted by the key
434    * ordering.
435    */
436   @Override public ImmutableSet<Entry<K, V>> entrySet() {
437     return super.entrySet();
438   }
439 
440   /**
441    * Returns an immutable sorted set of the keys in this map.
442    */
443   @Override public abstract ImmutableSortedSet<K> keySet();
444 
445   /**
446    * Returns an immutable collection of the values in this map, sorted by the
447    * ordering of the corresponding keys.
448    */
449   @Override public abstract ImmutableCollection<V> values();
450 
451   /**
452    * Returns the comparator that orders the keys, which is
453    * {@link Ordering#natural()} when the natural ordering of the keys is used.
454    * Note that its behavior is not consistent with {@link TreeMap#comparator()},
455    * which returns {@code null} to indicate natural ordering.
456    */
457   @Override
458   public Comparator<? super K> comparator() {
459     return keySet().comparator();
460   }
461 
462   @Override
463   public K firstKey() {
464     return keySet().first();
465   }
466 
467   @Override
468   public K lastKey() {
469     return keySet().last();
470   }
471 
472   /**
473    * This method returns a {@code ImmutableSortedMap}, consisting of the entries
474    * whose keys are less than {@code toKey}.
475    *
476    * <p>The {@link SortedMap#headMap} documentation states that a submap of a
477    * submap throws an {@link IllegalArgumentException} if passed a {@code toKey}
478    * greater than an earlier {@code toKey}. However, this method doesn't throw
479    * an exception in that situation, but instead keeps the original {@code
480    * toKey}.
481    */
482   @Override
483   public ImmutableSortedMap<K, V> headMap(K toKey) {
484     return headMap(toKey, false);
485   }
486 
487   /**
488    * This method returns a {@code ImmutableSortedMap}, consisting of the entries
489    * whose keys are less than (or equal to, if {@code inclusive}) {@code toKey}.
490    *
491    * <p>The {@link SortedMap#headMap} documentation states that a submap of a
492    * submap throws an {@link IllegalArgumentException} if passed a {@code toKey}
493    * greater than an earlier {@code toKey}. However, this method doesn't throw
494    * an exception in that situation, but instead keeps the original {@code
495    * toKey}.
496    *
497    * @since 12.0
498    */
499   @Override
500   public abstract ImmutableSortedMap<K, V> headMap(K toKey, boolean inclusive);
501 
502   /**
503    * This method returns a {@code ImmutableSortedMap}, consisting of the entries
504    * whose keys ranges from {@code fromKey}, inclusive, to {@code toKey},
505    * exclusive.
506    *
507    * <p>The {@link SortedMap#subMap} documentation states that a submap of a
508    * submap throws an {@link IllegalArgumentException} if passed a {@code
509    * fromKey} less than an earlier {@code fromKey}. However, this method doesn't
510    * throw an exception in that situation, but instead keeps the original {@code
511    * fromKey}. Similarly, this method keeps the original {@code toKey}, instead
512    * of throwing an exception, if passed a {@code toKey} greater than an earlier
513    * {@code toKey}.
514    */
515   @Override
516   public ImmutableSortedMap<K, V> subMap(K fromKey, K toKey) {
517     return subMap(fromKey, true, toKey, false);
518   }
519 
520   /**
521    * This method returns a {@code ImmutableSortedMap}, consisting of the entries
522    * whose keys ranges from {@code fromKey} to {@code toKey}, inclusive or
523    * exclusive as indicated by the boolean flags.
524    *
525    * <p>The {@link SortedMap#subMap} documentation states that a submap of a
526    * submap throws an {@link IllegalArgumentException} if passed a {@code
527    * fromKey} less than an earlier {@code fromKey}. However, this method doesn't
528    * throw an exception in that situation, but instead keeps the original {@code
529    * fromKey}. Similarly, this method keeps the original {@code toKey}, instead
530    * of throwing an exception, if passed a {@code toKey} greater than an earlier
531    * {@code toKey}.
532    *
533    * @since 12.0
534    */
535   @Override
536   public ImmutableSortedMap<K, V> subMap(K fromKey, boolean fromInclusive, K toKey,
537       boolean toInclusive) {
538     checkNotNull(fromKey);
539     checkNotNull(toKey);
540     checkArgument(comparator().compare(fromKey, toKey) <= 0,
541         "expected fromKey <= toKey but %s > %s", fromKey, toKey);
542     return headMap(toKey, toInclusive).tailMap(fromKey, fromInclusive);
543   }
544 
545   /**
546    * This method returns a {@code ImmutableSortedMap}, consisting of the entries
547    * whose keys are greater than or equals to {@code fromKey}.
548    *
549    * <p>The {@link SortedMap#tailMap} documentation states that a submap of a
550    * submap throws an {@link IllegalArgumentException} if passed a {@code
551    * fromKey} less than an earlier {@code fromKey}. However, this method doesn't
552    * throw an exception in that situation, but instead keeps the original {@code
553    * fromKey}.
554    */
555   @Override
556   public ImmutableSortedMap<K, V> tailMap(K fromKey) {
557     return tailMap(fromKey, true);
558   }
559 
560   /**
561    * This method returns a {@code ImmutableSortedMap}, consisting of the entries
562    * whose keys are greater than (or equal to, if {@code inclusive})
563    * {@code fromKey}.
564    *
565    * <p>The {@link SortedMap#tailMap} documentation states that a submap of a
566    * submap throws an {@link IllegalArgumentException} if passed a {@code
567    * fromKey} less than an earlier {@code fromKey}. However, this method doesn't
568    * throw an exception in that situation, but instead keeps the original {@code
569    * fromKey}.
570    *
571    * @since 12.0
572    */
573   @Override
574   public abstract ImmutableSortedMap<K, V> tailMap(K fromKey, boolean inclusive);
575 
576   @Override
577   public Entry<K, V> lowerEntry(K key) {
578     return headMap(key, false).lastEntry();
579   }
580 
581   @Override
582   public K lowerKey(K key) {
583     return keyOrNull(lowerEntry(key));
584   }
585 
586   @Override
587   public Entry<K, V> floorEntry(K key) {
588     return headMap(key, true).lastEntry();
589   }
590 
591   @Override
592   public K floorKey(K key) {
593     return keyOrNull(floorEntry(key));
594   }
595 
596   @Override
597   public Entry<K, V> ceilingEntry(K key) {
598     return tailMap(key, true).firstEntry();
599   }
600 
601   @Override
602   public K ceilingKey(K key) {
603     return keyOrNull(ceilingEntry(key));
604   }
605 
606   @Override
607   public Entry<K, V> higherEntry(K key) {
608     return tailMap(key, false).firstEntry();
609   }
610 
611   @Override
612   public K higherKey(K key) {
613     return keyOrNull(higherEntry(key));
614   }
615 
616   @Override
617   public Entry<K, V> firstEntry() {
618     return isEmpty() ? null : entrySet().asList().get(0);
619   }
620 
621   @Override
622   public Entry<K, V> lastEntry() {
623     return isEmpty() ? null : entrySet().asList().get(size() - 1);
624   }
625 
626   /**
627    * Guaranteed to throw an exception and leave the map unmodified.
628    *
629    * @throws UnsupportedOperationException always
630    * @deprecated Unsupported operation.
631    */
632   @Deprecated
633   @Override
634   public final Entry<K, V> pollFirstEntry() {
635     throw new UnsupportedOperationException();
636   }
637 
638   /**
639    * Guaranteed to throw an exception and leave the map unmodified.
640    *
641    * @throws UnsupportedOperationException always
642    * @deprecated Unsupported operation.
643    */
644   @Deprecated
645   @Override
646   public final Entry<K, V> pollLastEntry() {
647     throw new UnsupportedOperationException();
648   }
649 
650   private transient ImmutableSortedMap<K, V> descendingMap;
651 
652   @Override
653   public ImmutableSortedMap<K, V> descendingMap() {
654     ImmutableSortedMap<K, V> result = descendingMap;
655     if (result == null) {
656       result = descendingMap = createDescendingMap();
657     }
658     return result;
659   }
660 
661   abstract ImmutableSortedMap<K, V> createDescendingMap();
662 
663   @Override
664   public ImmutableSortedSet<K> navigableKeySet() {
665     return keySet();
666   }
667 
668   @Override
669   public ImmutableSortedSet<K> descendingKeySet() {
670     return keySet().descendingSet();
671   }
672 
673   /**
674    * Serialized type for all ImmutableSortedMap instances. It captures the
675    * logical contents and they are reconstructed using public factory methods.
676    * This ensures that the implementation types remain as implementation
677    * details.
678    */
679   private static class SerializedForm extends ImmutableMap.SerializedForm {
680     private final Comparator<Object> comparator;
681     @SuppressWarnings("unchecked")
682     SerializedForm(ImmutableSortedMap<?, ?> sortedMap) {
683       super(sortedMap);
684       comparator = (Comparator<Object>) sortedMap.comparator();
685     }
686     @Override Object readResolve() {
687       Builder<Object, Object> builder = new Builder<Object, Object>(comparator);
688       return createMap(builder);
689     }
690     private static final long serialVersionUID = 0;
691   }
692 
693   @Override Object writeReplace() {
694     return new SerializedForm(this);
695   }
696 
697   // This class is never actually serialized directly, but we have to make the
698   // warning go away (and suppressing would suppress for all nested classes too)
699   private static final long serialVersionUID = 0;
700 }